home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 23 / Amiga Format AFCD23 (Feb 1998, Issue 107).iso / -in_the_mag- / emulation / cpu / z80 / z80.h < prev    next >
C/C++ Source or Header  |  1997-12-12  |  13KB  |  388 lines

  1. #ifndef Z80_H
  2. #define Z80_H
  3. /*
  4.  * C header file for the Z80 emulator.
  5.  *
  6.  * All (or most) of these types have to be defined (and to the correct
  7.  * sizes):    BYTE, UBYTE, WORD, UWORD, LONG and ULONG.
  8.  *
  9.  * If Z80_ENVDATA is defined, the last element of struct Z80_Control will
  10.  * be a structure named Envdata, of the type "struct Z80_Envdata", which
  11.  * you also must have defined.
  12.  *
  13.  */
  14.  
  15.  
  16.   /* All sizes and offsets are in bytes: */
  17.  
  18.     /* The amount of bytes needed for the Z80 memory space */
  19. #define Z80_MEMSIZE    0x10000
  20.  
  21. #define Z80_LBUFSIZE    16  /* Uninteresting to the normal user */
  22. #define Z80_HBUFSIZE    16
  23.  
  24.     /* The size of the memory used for the cache.
  25.         It must be word-aligned! */
  26. #define Z80_CACHESIZE    ((2*Z80_MEMSIZE)+Z80_LBUFSIZE+Z80_HBUFSIZE)
  27.  
  28.     /* The space needed for memory control flags */
  29. #define Z80_FLAGMEMSIZE Z80_MEMSIZE
  30.  
  31.   /* Memory write access control flags:
  32.  
  33.     ;Memory flag values (signed byte):
  34.     ;    -1 to -128    read-only
  35.     ;    0        ok to write (no detection)
  36.     ;    1 to 16     access counters 1 to 16
  37.     ;    17 to 63    reserved
  38.     ;    64 to 127    user exception
  39.  
  40.     Call Z80_SetMemFlag (described below) to set these flags.
  41.     A zero flag marks ordinary RAM, and no detection is made.
  42.     A negative flag (use Z80_MEM_ROM) marks read-only memory. Attempts
  43.     to write are ignored.
  44.       A value in the range Z80_MEM_CNT to Z80_MEM_CNT+Z80_MEM_CNTNUM-1
  45.     corresponds to write a access counter from 0 to Z80_MEM_CNTNUM-1.
  46.     On each write access, the corresponding counter in the Z80_AccessCnt
  47.     array is incremented by one. If the corresponding flag in the
  48.     Z80_CntType array is zero, the value is written, otherwise the attempt
  49.     to write is ignored.
  50.       A value in the range Z80_MEM_USR to Z80_MEM_USR+Z80_MEM_USRNUM-1
  51.     corresponds to a user memory exception from 0 to Z80_MEM_USRNUM-1.
  52.     If the Z80_MemHandler pointer is nonzero (non-NULL), the routine it
  53.     points to is called with the following parameters:
  54.     d1 contains the exception number (word).
  55.     d2 contains the value (byte).
  56.     a1 contains the Z80 address (word).
  57.     a2 is scratch (address of user-def routine).
  58.     Changes to a1 and a2 have no effect. The handler must protect any other
  59.     registers it uses, and return the following values:
  60.     d1 zero (longword) if value should be written, nonzero if not.
  61.     d2 countains the value (byte).
  62.     The memory handler call is mostly intended for more complex cases of
  63.     write access detection than the simple counters can handle. Not many
  64.     details can be found out about the current Cpu status from the memory
  65.     handler, since it is called in mid-execution of an instruction, and only
  66.     the base pointer registers TableB, Z0, CacheB and FlagsB can be trusted
  67.     to have correct values. For a list of register aliases, see the file
  68.     Z80_coding.i.
  69.  
  70.     Example in C:
  71.     Z80_SetMemFlag(Control, $4000, $1B00, Z80_MEM_CNT+5);
  72.     flags the area from $4000 to $5AFF as access counter 5.
  73.     Z80_CntType[5] = 1;
  74.     sets the type of counter 5 to 'do not write'.
  75.     (Remember: the range is from 0 to Z80_MEM_CNTNUM - 1.)
  76.   */
  77.  
  78. #define Z80_MEM_ROM    (-1)
  79. #define Z80_MEM_CNT    1
  80. #define Z80_MEM_CNTNUM    16
  81. #define Z80_MEM_USR    64
  82. #define Z80_MEM_USRNUM    (128-Z80_MEM_USR)
  83.  
  84.  
  85. struct Z80_Control {
  86.     LONG    Workspace;    /* temporary storage, byte swapping and so on */
  87.  
  88.     ULONG   AccessCnt[Z80_MEM_CNTNUM];    /* Memory write access counters */
  89.  
  90. #define Z80_BCDSTACKSIZE 7    /* BCD stack (must be word-aligned!) */
  91.     BYTE    Z80_BCDstack[6*Z80_BCDSTACKSIZE];
  92.  
  93.     BYTE    CntType[Z80_MEM_CNTNUM];
  94.         /* Counter type designations. Zero for write,
  95.             nonzero for no write. */
  96.  
  97.     UBYTE   Parity[256];  /* Parity translation table */
  98.  
  99.   /* Public: */
  100.     BYTE *  Memory;  /* Pointer to the Z80 address space memory */
  101.     WORD *  Cachemem;  /* Pointer to the cache memory */
  102.  
  103.   /* Public: */
  104.     BYTE *  Flagmem;    /* Pointer to the flag memory */
  105.     void *  MemHandler; /* Pointer to User Memory Exception Handler */
  106.  
  107.   /* Public (read-only): */
  108.     BYTE *  zero;  /* Pointer to Z80 address 0. The (signed)
  109.               word-sized Z80 registers (like Z80_HL)
  110.               can be used as offsets from this base
  111.               to access the Z80 memory space. */
  112.     WORD *  cachezero; /* Corresponds to Z80_zero in cache memory */
  113.     BYTE *  flagzero;  /* Corresponds to Z80_zero in flag memory */
  114.  
  115.   /* Public (read-only): */
  116.     WORD    Running;  /* Nonzero if running, zero if not */
  117.  
  118.     /* Private: */
  119.     WORD    Request;  /* Request pointer (offset from InstrBase) */
  120.     WORD    ReqLvl;  /* Priority level of current request */
  121.     UWORD   alt_CCR;  /* This is the internal F' in CCR format */
  122.     WORD    BCD_SP;  /* Stack pointer for the BCD stack */
  123.  
  124.     /* Must be word-aligned here! */
  125.  
  126.   /* The Cpu Status structure (public fields):
  127.  
  128.     Fields storing a register have simply the register's name.
  129.     The alternative registers are referred to as alt_<register>.
  130.       <register> here is one of:
  131.     byte-valued    A, B, C, D, E, H, L, F, I, R
  132.     word-valued    HL, IX, IY, SP, PC
  133.     special     IFF, INTMOD
  134.     Accessing HL will affect H and L and vice versa (HL is an 'alias').
  135.     Only the word-valued entries are guaranteed to also be word-aligned.
  136.     IFF and INTMOD are byte-sized, and should be interpreted as follows:
  137.     IFF    Bit 7 holds IFF2. Bit 6 holds IFF1. Bits 5-0 are zero.
  138.     INTMOD    The values in the range -1 to 1 correspond to interrupt
  139.         modes 0 to 2, respectively.
  140.  
  141.     None of these entries should be written to (and rather not read either)
  142.     unless the emulator is stopped, since their contents are then undefined.
  143.     Most are never updated or read from except upon exiting and continuing.
  144.  
  145.   */
  146.  
  147.     struct CpuStatus {
  148.     BYTE    pad_d0_3, alt_A, pad_d0_1, A;
  149.     BYTE    pad_d1_3, alt_B, pad_d1_1, B;
  150.     BYTE    pad_d2_3, alt_C, pad_d2_1, C;
  151.     BYTE    pad_d3_3, alt_D, pad_d3_1, D;
  152.     BYTE    pad_d4_3, alt_E, pad_d4_1, E;
  153.     WORD    pad_d5_u;
  154.     union {
  155.       WORD w;  /* HL can be word-accessed as s.Cpu.HL.w */
  156.       struct {
  157.         BYTE H;
  158.         BYTE L;
  159.       } b;       /* or byte accessed as s.Cpu.HL.b.H (or L) */
  160.     } HL;
  161.  
  162.     WORD    pad_a2_u;
  163.     WORD    SP;
  164.  
  165.     /* Private fields */
  166.     LONG    pad_a3, pad_a4, pad_a5, pad_a6;
  167.  
  168.     union {
  169.       WORD w;  /* IX can be word-accessed as s.Cpu.IX.w */
  170.       struct {
  171.         BYTE H;
  172.         BYTE L;
  173.       } b;       /* or byte accessed as s.Cpu.IX.b.H (or L) */
  174.     } IX;
  175.  
  176.     union {
  177.       WORD w;  /* IY can be word-accessed as s.Cpu.IY.w */
  178.       struct {
  179.         BYTE H;
  180.         BYTE L;
  181.       } b;       /* or byte accessed as s.Cpu.IY.b.H (or L) */
  182.     } IY;
  183.  
  184.     union {
  185.       WORD w;  /* H'L' can be word-accessed as s.Cpu.alt_HL.w */
  186.       struct {
  187.         BYTE H;
  188.         BYTE L;
  189.       } b;       /* or byte accessed as s.Cpu.alt_HL.b.H (or L) */
  190.     } alt_HL;
  191.  
  192.     WORD    PC;  /* PC (written/read only at exit/continue) */
  193.  
  194.     BYTE    F;     /* These flags are calculated upon exit. */
  195.     BYTE    alt_F; /*  During emulation, they are unused.    */
  196.  
  197.     BYTE    IFF;     /* IFF2 in bit 7, IFF1 in bit 6 */
  198.     BYTE    INTMOD;  /* Interruptmode (-1 to 1) = (modes 0 to 2) */
  199.     BYTE    I;
  200.     BYTE    R;  /* Only bit 7 is valid. See "notes.txt" */
  201.     /* word aligned here */
  202.  
  203.     /* These could be inspected. If nonzero, a request has been
  204.        received but not yet served. */
  205.     WORD    INT_FF; /* INTreq status */
  206.     WORD    NMI_FF; /* NMIreq status */
  207.     WORD    RES_FF; /* RESETreq status */
  208.  
  209.     WORD    BCD_OP;   /* BCD operation */
  210.     UWORD    BCD_C;      /* BCD carry, in bit 0 */
  211.     BYTE    BCD_A;      /* BCD destination */
  212.     BYTE    BCD_B;      /* BCD source */
  213.  
  214.     } Cpu;
  215.  
  216. #ifdef Z80_ENVDATA
  217.   /* User environment data area. Should be word-aligned here. */
  218.     struct Z80_Envdata Envdata;
  219. #endif
  220.  
  221. };  /* end of struct Z80_Control */
  222.  
  223.  
  224.  
  225.   /* Function prototypes and descriptions */
  226.  
  227.  
  228. int Z80_Init(struct Z80_Control *);
  229.  
  230.   /* Before the emulator is started, the control structure must be
  231.      initialised by calling Z80_Init() with a pointer to the structure.
  232.        The fields Z80_Memory and Z80_Cachemem must be pointing to
  233.      allocated memory. If the memory write access checking feature is
  234.      used, the field Z80_Flagmem must also be set, and if Z80_MemHandler
  235.      is nonzero it is assumed to point to a user memory exception handler.
  236.      See memory flag definitions above for details.
  237.        The user environment data area is not changed. All other fields
  238.      are automatically initialised. The Cpu Status fields are set up as
  239.      after a reset.
  240.        The return value is nonzero if an error occurred, and zero
  241.      otherwise.
  242.   */
  243.  
  244.  
  245. int Z80_Coldstart(struct Z80_Control *);
  246.  
  247.   /* The emulator is started 'from scratch' with a CPU reset through a
  248.      call to Z80_Coldstart. A pointer to a control structure must be
  249.      given, and the structure must be initialised (see Z80_Init above).
  250.        The return value is nonzero if an error occurred, and zero
  251.      otherwise.
  252.   */
  253.  
  254.  
  255. int Z80_Continue(struct Z80_Control *);
  256.  
  257.   /* Continue as if nothing happened since last exit (unless the saved
  258.      processor status has been manipulated). A pointer to a control
  259.      structure must be given.
  260.        Changes to other fields than the Cpu status structure entries
  261.      are not recommended; calling Z80_Continue does not guarantee
  262.      that such changes have any effect (see Z80_NewSettings).
  263.        The return value is the same as for Z80_Coldstart.
  264.   */
  265.  
  266.  
  267.   /* About reallocating memory:
  268.  
  269.      Call Z80_Exitreq and make sure the emulator has stopped before
  270.      reallocating memory (remember to copy the old memory contents to the
  271.      new areas), then update the corresponding entries in the control
  272.      structure (Z80_Memory, Z80_Cachemem and Z80_Flagmem). Calling
  273.      Z80_NewSettings will then make sure that Z80_Continue will resume
  274.      the emulation from the new addresses.
  275.        The control structure can be moved whenever the emulator is not
  276.      running, without doing anything other than passing the new address
  277.      to Z80_Continue.
  278.   */
  279.  
  280. int Z80_NewSettings(struct Z80_Control *);
  281.  
  282.   /* This subroutine makes the emulator update the private fields of the
  283.      control structure when changes to any of the public fields have taken
  284.      place, for instance if the Z80_Memory field is changed. Do not call
  285.      this routine while the emulator is running.
  286.        The return value is nonzero if an error occurred, and zero
  287.        otherwise.
  288.   */
  289.  
  290.  
  291. void Z80_SetByte(struct Z80_Control *, UWORD addr, BYTE val);
  292.  
  293. void Z80_SetWordLH(struct Z80_Control *, UWORD addr, UWORD val);
  294.  
  295. BYTE Z80_GetByte(struct Z80_Control *, UWORD addr);
  296.  
  297. WORD Z80_GetWordLH(struct Z80_Control *, UWORD addr);
  298.  
  299. void Z80_SetBlock(struct Z80_Control *,
  300.     UWORD start_addr, ULONG size, BYTE val);
  301.  
  302. void Z80_ReadBlock(struct Z80_Control *,
  303.     void *buffer, UWORD start_addr, ULONG size);
  304.  
  305. void Z80_WriteBlock(struct Z80_Control *,
  306.     void *buffer, UWORD start_addr, ULONG size);
  307.  
  308.   /* Routines to access the Z80 address space.
  309.      All need a pointer to the control structure and a word-sized Z80
  310.      address (for block functions this is the block start address).
  311.        Z80_SetByte is passed a byte value to be written. It returns
  312.      nothing.
  313.        Z80_SetWordLH is passed a (high-end first) word value to be written
  314.      and writes it low-end first. It returns nothing.
  315.        Z80_GetByte returns the byte value.
  316.        Z80_GetWordLH reads a (low-end first) word value and returns it
  317.      high-end first.
  318.        All block functions are passed the block size as an unsigned
  319.      longword. They return nothing.
  320.        Z80_SetBlock is also passed the byte value to be written.
  321.        Z80_ReadBlock and Z80_WriteBlock are passed the buffer address
  322.      (in the 680x0 address space) as a pointer to void.
  323.        All Z80 address arithmetic is word-sized. For instance, calling
  324.      Z80_SetWordLH(ctrl, 0xffff, 0x1234) will set address $ffff to $34
  325.      and address $0000 to $12. The block functions will also wrap at $ffff.
  326.   */
  327.  
  328.  
  329. void Z80_SetMemFlag(struct Z80_Control *,
  330.     UWORD start_addr, ULONG size, BYTE flag);
  331.  
  332.   /* Sets memory flags.
  333.      Takes a pointer to a control structure, a (word-sized) Z80 address,
  334.      the block size (an unsigned longword) and the flag value (a byte) as
  335.      parameters. Nothing is returned. For ranges of flag values, see the
  336.      definition of memory write access control flags above.
  337.   */
  338.  
  339. BYTE Z80_GetMemFlag(struct Z80_Control *, UWORD addr);
  340.  
  341.   /* Returns the memory flag value for an address.
  342.      Takes a pointer to a control structure and a (word-sized) Z80
  343.      address as parameters. It returns a byte-sized flag. For ranges of
  344.      flag values, see the definition of memory write access control flags
  345.      above.
  346.   */
  347.  
  348.  
  349.   /* The requests could be called from hardware interrupts, keypresses,
  350.      menus or whatever. They do not affect any registers (apart from CCR),
  351.      and return nothing.
  352.      They all need a pointer to the control structure.
  353.  
  354.      The detection time is currently not guaranteed to be anything.
  355.      Hopefully, it is always finite. It shouldn't be more than a few
  356.      emulated Z80 instructions.
  357.   */
  358.  
  359.  
  360. void Z80_EXITreq(struct Z80_Control *);
  361.   /*
  362.     The emulation can only be interrupted between (Z80) instructions, as
  363.     with the Z80 processor interrupts (and presently only after *certain*
  364.     Z80 instructions). Therefore, stopping the emulator 'from the outside'
  365.     is just another request call.
  366.   */
  367.  
  368.  
  369. void Z80_INTreq(struct Z80_Control *);
  370. /*
  371.     Emulates pulling the INT line low.
  372. */
  373.  
  374.  
  375. void Z80_NMIreq(struct Z80_Control *);
  376. /*
  377.     Emulates a Non-Maskable Interrupt. (Negative edge triggered
  378.     on a real Z80.)
  379. */
  380.  
  381.  
  382. void Z80_RESETreq(struct Z80_Control *);
  383. /*
  384.     Emulates pulling the RESET line low.
  385. */
  386.  
  387. #endif /* Z80.h */
  388.